<?php
Decorator
//шаблок декоратор працює приблизно так є базовий клас який слугує моделлю для створення його розширеного класу і цей розширений передається іншим класам в конструктор після чого вони міняють його властивості на вигляд і т.д.
  function writeln($line_in) {
    echo $line_in."<br/>";
  }
// клас бук має закриті властивості автор і заголовок і відкориті методи для їх зчитування. При створенні обєкту конструктор присвоює їм передані значення.
class Book {
    private $author;
    private $title;
    function __construct($title_in, $author_in) {
        $this->author = $author_in;
        $this->title  = $title_in;
    }
    function getAuthor() {
        return $this->author;
    }
    function getTitle() {
        return $this->title;
    }
    function getAuthorAndTitle() {
      return $this->getTitle().' by '.$this->getAuthor();
    }
}
//клас має відкриті тільки для нащадків властивості автор і заголовок. Конструктор приймає обєкт типу бук і присвоює його своїй властивості. Відкриті методи можуть змінити і показати заголовок. По суті цей клас є кешом між оригінальним обєктом і класами які далі змінюють - декорують його
class BookTitleDecorator {
    protected $book;
    protected $title;
    public function __construct(Book $book_in) {
        $this->book = $book_in;
        $this->resetTitle();
    }   
    //повертає початковий вміст заголовку в свою властивість
    function resetTitle() {
        $this->title = $this->book->getTitle();
    }
	//виводить початковий заголовок
    function showTitle() {
        return $this->title;
    }
}
//цей обєкт приймає в свій конструктор обєкт типу BookTitleDecorator хоча одночасно є його ж розширенням
class BookTitleExclaimDecorator extends BookTitleDecorator {
    private $btd;
    public function __construct(BookTitleDecorator $btd_in) {
        $this->btd = $btd_in;
    }
	//додає знаки оклику до заголовків
    function exclaimTitle() {
        $this->btd->title = "!" . $this->btd->title . "!";
    }
}
//аналогічно попередньому класу цей розширює BookTitleDecorator і приймає  в свій конструктор його тип. Даліі змінює при видачі його заголовок
class BookTitleStarDecorator extends BookTitleDecorator {
    private $btd;
    public function __construct(BookTitleDecorator $btd_in) {
        $this->btd = $btd_in;
    }
	//додає зірочки до заголовків
    function starTitle() {
        $this->btd->title = Str_replace(" ","*",$this->btd->title);
    }
}


//створюємо обєкт класу бук з авторами і заголовком
  $patternBook = new Book('Gamma, Helm, Johnson, and Vlissides', 'Design Patterns');
 //створюємо обєкт BookTitleDecorator
  $decorator = new BookTitleDecorator($patternBook);
  //передаємо обєкт для подальшої зміни його властивостей
  $starDecorator = new BookTitleStarDecorator($decorator);
  $exclaimDecorator = new BookTitleExclaimDecorator($decorator);
 
 
  writeln($decorator->showTitle());
  
writeln('');
  //двічі додаємо по знаку оклику
  $exclaimDecorator->exclaimTitle();
  $exclaimDecorator->exclaimTitle();
  //один раз виводимо заголовок 
  writeln($decorator->showTitle());

 writeln('');
  writeln('showing title after star added : ');
  $starDecorator->starTitle();
  writeln($decorator->showTitle());
  
 writeln('');
  writeln('showing title after reset: ');
  writeln($decorator->resetTitle());
  writeln($decorator->showTitle());
==============
Singleton
//цей шаблон дає можливість обмежити створення обєкту класу одним екземпляром. Робиться це через оголошення його конструктора приватним і через метод getInstance() створення його єдиного екземпляру
<?php 
class Singleton
{
   
    public static function getInstance()
    {
        static $instance = null;
        if (null === $instance) {
            $instance = new Singleton();
        }

        return $instance;
    }

    /**
     * Protected constructor to prevent creating a new instance of the
     * *Singleton* via the `new` operator from outside of this class.
     */
    protected function __construct()
    {
    }

    /**
     * Private clone method to prevent cloning of the instance of the
     * *Singleton* instance.
     *
     * @return void
     */
    private function __clone()
    {
    }

    /**
     * Private unserialize method to prevent unserializing of the *Singleton*
     * instance.
     *
     * @return void
     */
    private function __wakeup()
    {
    }
}

class SingletonChild extends Singleton
{
}

$obj = Singleton::getInstance();
var_dump($obj === Singleton::getInstance());             // bool(true)

$anotherObj = SingletonChild::getInstance();
var_dump($anotherObj === Singleton::getInstance());      // bool(false)

var_dump($anotherObj === SingletonChild::getInstance()); // bool(true)
================
The Registry class – holds an array in which all  objects could be placed in and getters and setters to access them. We make this class as singleton to avoid duplication.
	
class Registry {
   private $registry = array();
   private static $instance = null;
 
  public static function getInstance() {
     if(self::$instance === null) {
        self::$instance = new Registry();
     }
 
     return self::$instance;
  }
 
  private function __construct() {}
  private function __clone() {}
 
   public function set($key, $value) {
      if (isset($this->registry[$key])) {
         throw new Exception("There is already an entry for key " . $key);
      }
 
      $this->registry[$key] = $value;
   }
 
   public function get($key) {
      if (!isset($this->registry[$key])) {
         throw new Exception("There is no entry for key " . $key);
      }
 
      return $this->registry[$key];
   }
}
Next example shows using of this class
// Import all needed libraries.
   require_once('core/registry/Registry.php');
 
   try {
      require_once('core/config/IniConfiguration.php');
 
      // Get an instance of the Registry, ...
      $registry = Registry::getInstance();
      
      // ... load the basic config and add it to the registry.
      $registry->set('config', new IniConfiguration('config.ini.php'));
      
      // Then load the database connection parameters, ...
      $db = $registry->get('config')->getSection('database');
      
      // ... create the pdo mysql string, ...
      $pdoString = "mysql:host=" . $db['host'] . ";dbname=" . $db['name'];
      
      // ... initialize the database connection object ...
      $pdo = new PDO($pdoString, $db['user'], $db['pwd']);
      
      // ... and add it to the registry too.
      $registry->set('pdo', $pdo);
   } catch(Exception $e) {
      echo $e->getMessage();
   }
===========
In the Observer pattern a subject object will notify an observer object if the subject's state changes.

In this example, the PatternSubject is the subject, and the PatternObserver is the observer. For the observer to be notified of changes in the subject it must first be registered with the subject using the attach method. For the observer to no longer be notified of changes in the subject it must be unregistered with the detatch method.

When the subject changes it calls the observer's update method with itself. The observer can then take the subject and use whatever methods have been made available for it to determine the subjects current state.

The Observer Pattern is often called Publish-Subscribe, where the subject would be the publisher, and the observer would be the subscriber.
<?php

abstract class AbstractObserver {
    abstract function update(AbstractSubject $subject_in);
}

abstract class AbstractSubject {
    abstract function attach(AbstractObserver $observer_in);
    abstract function detach(AbstractObserver $observer_in);
    abstract function notify();
}

function writeln($line_in) {
    echo $line_in."<br/>";
}

class PatternObserver extends AbstractObserver {
    public function __construct() {
    }
    public function update(AbstractSubject $subject) {
      writeln('*IN PATTERN OBSERVER - NEW PATTERN GOSSIP ALERT*');
      writeln(' new favorite patterns: '.$subject->getFavorites());
      writeln('*IN PATTERN OBSERVER - PATTERN GOSSIP ALERT OVER*');      
    }
}

class PatternSubject extends AbstractSubject {
    private $favoritePatterns = NULL;
    private $observers = array();
    function __construct() {
    }
    function attach(AbstractObserver $observer_in) {
      //could also use array_push($this->observers, $observer_in);
      $this->observers[] = $observer_in;
    }
    function detach(AbstractObserver $observer_in) {
      //$key = array_search($observer_in, $this->observers);
      foreach($this->observers as $okey => $oval) {
        if ($oval == $observer_in) { 
          unset($this->observers[$okey]);
        }
      }
    }
	//в цьому методі іде перебір масиву з обєктами обзерверів які по черзі задіюють свій метод ->update( якому передається поточний обєкт для обробки і виведення чи передачі даних про нього. Тут цей метод викликаєсться всередині методу updateFavorites(, але він може викликатися в будь-якому місці коду класу.
    function notify() {
      foreach($this->observers as $obs) {
        $obs->update($this);
      }
    }
    function updateFavorites($newFavorites) {
      $this->favorites = $newFavorites;
      $this->notify();
    }
    function getFavorites() {
      return $this->favorites;
    }
}

  $patternGossiper = new PatternSubject();
  $patternGossipFan = new PatternObserver();
  $patternGossiper->attach($patternGossipFan);
  $patternGossiper->updateFavorites('abstract factory, decorator, visitor');
  $patternGossiper->updateFavorites('abstract factory, observer, decorator');
  $patternGossiper->detach($patternGossipFan);
  $patternGossiper->updateFavorites('abstract factory, observer, paisley');

?>

=============
Factory

One of the most commonly used design patterns is the factory pattern. In this pattern, a class simply creates the object you want to use. Consider the following example of the factory pattern:

<?php
class Automobile
{
    private $vehicleMake;
    private $vehicleModel;

    public function __construct($make, $model)
    {
        $this->vehicleMake = $make;
        $this->vehicleModel = $model;
    }

    public function getMakeAndModel()
    {
        return $this->vehicleMake . ' ' . $this->vehicleModel;
    }
}

class AutomobileFactory
{
    public static function create($make, $model)
    {
        return new Automobile($make, $model);
    }
}

// have the factory create the Automobile object
$veyron = AutomobileFactory::create('Bugatti', 'Veyron');

print_r($veyron->getMakeAndModel()); // outputs "Bugatti Veyron"
This code uses a factory to create the Automobile object. There are two possible benefits to building your code this way; the first is that if you need to change, rename, or replace the Automobile class later on you can do so and you will only have to modify the code in the factory, instead of every place in your project that uses the Automobile class. The second possible benefit is that if creating the object is a complicated job you can do all of the work in the factory, instead of repeating it every time you want to create a new instance.

Using the factory pattern isn’t always necessary (or wise). The example code used here is so simple that a factory would simply be adding unneeded complexity. However if you are making a fairly large or complex project you may save yourself a lot of trouble down the road by using factories.
==========
Command
If you are familiar with C or Php, you have probably already encountered Command as its procedural equivalent: the callback, which is usually implemented as a function pointer or a data structure such as a string or an array in php.
Command is an abstraction over a method call, which becomes a first-class object with all the benefits of object orientation over a set of routines: composition, inheritance and handling.
For example, the GoF book proposes to use Commands to store a chain of user actions and supporting undoing and redoing operations.
Note that php 5.3 functional programming capabilities (Closures) can be used as a native implementation of the Command pattern. Though, there is an advantage in type safety in using an abstract data type for every Command hierarchy.

In this pattern, the Invoker knows that a Command is passed to it, without dependencies on the actual ConcreteCommand implementation. The solved problem is the association of method calls by configuration: for instance ui controls like buttons and menus refer to a Command and assume their behavior by composing a generic ConcreteCommand instance.

Participants:
Command: defines an abstraction over a method call.
ConcreteCommand: implementation of an operation.
Invoker: refers to Command instances as its available operations.
The code sample provides Validator components implemented as Command objects.
<?php
/**
 * The Command abstraction.
 * In this case the implementation must return a result,
 * sometimes it only has side effects.
 */
interface Validator
{
    /**
     * The method could have any parameters.
     * @param mixed
     * @return boolean
     */
    public function isValid($value);
}

/**
 * ConcreteCommand.
 */
class MoreThanZeroValidator implements Validator
{
    public function isValid($value)
    {
        return $value > 0;
    }
}

/**
 * ConcreteCommand.
 */
class EvenValidator implements Validator
{
    public function isValid($value)
    {
        return $value % 2 == 0;
    }
}

/**
 * The Invoker. An implementation could store more than one
 * Validator if needed.
 */
class ArrayProcessor
{
    protected $_rule;

    public function __construct (Validator $rule)
    {
        $this->_rule = $rule;
    }

    public function process(array $numbers)
    {
        foreach ($numbers as $n) {
            if ($this->_rule->IsValid($n)) {
                echo $n, "\n";
            }
        }
    }
}

// Client code
$processor = new ArrayProcessor(new EvenValidator());
$processor->process(array(1, 20, 18, 5, 0, 31, 42));
Some implementation notes for this pattern:
some of the parameters for the method call can be provided at the construction of the ConcreteCommand, effectively currying the original method.
A Command can be considered as a very simple Strategy, with only one method, and the emphasis put on the operation as an object you can pass around.
ConcreteCommands also compose every resource they need to achieve their goal, primarily the Receiver of the action where they call method to execute a Command.
Composite, Decorator and other patterns can be mixed with the Command one, obtaining multiple Commands, decorated Commands and so on.
===========
Strategy

interface PricingStrategy {
    function price() {}
}
 
abstract class PriceStrategy implements PricingStrategy {
    function __construct() {}
    function price() {}
}
 
class FixedPriceStrategy extends PriceStrategy {
    function price() {
        return $fixed_rate_price;
    }
}
 
class HourlyPriceStrategy extends PriceStrategy {
    function price() {
        return $hours * $hourly_rate;
    }
}
 
class Project {
   public $pricing_structure;
 
    function __construct(PriceStrategy $pricing_strategy) {
        $this->pricing_structure = $pricing_strategy;
    }
}
0000000000000000000
$project = new Project(new FixedPriceStrategy());
 
echo 'The cost of this project is: '.$project->pricing_structure->Price();

===========PRINTED=====================















